// Copyright (c) 2022 Presto Labs Pte. Ltd.
// Author: fengyang

#pragma once

#include "coin2/exchange/base/feed_util/kline.h"

namespace coin2::exchange::base::feed::replay {

// only support snapshot as the most of cases are light_bbo and move2bp
enum class KlineEventType {
  Unknow,
  Clear,
  Snapshot,
  Add,
  Freeze,
  Remove,
};

struct KlinesEvent {
  KlineEventType type;
  std::vector<Kline> klines;
};

class KlineEventBuilder {
 public:
  KlineEventBuilder() {
  }

  KlinesEvent ToEvent(std::string_view native_symbol, const Klines& klines) {
    auto kline = klines.Get();
    CHECK(kline);
    const auto& interval = kline.value()->interval;
    auto k = std::make_pair(std::string(native_symbol), interval);
    auto ts_iter = last_timestamp_.find(k);
    int64_t last_timestamp = 0;
    if (ts_iter != last_timestamp_.end()) {
      last_timestamp = ts_iter->second;
    }

    KlinesEvent event;
    event.type = KlineEventType::Add;

    Klines::Iterator iter = klines.Begin();
    int capacity = 0;
    for ( ; iter != klines.End(); iter++) {
      if (iter->timestamp <= last_timestamp) break;

      capacity++;
    }

    if (capacity > 0) {
      last_timestamp_[k] = klines.Begin()->timestamp;
    }

    event.klines.resize(capacity);
    for (int idx =0; idx < capacity; idx++) {
      event.klines[idx] = *(klines.Get(capacity - idx -1).value());
    }

    return event;
  };

 private:
  std::map<std::pair<std::string, fastfeed::proto::KlineInterval>, int64_t> last_timestamp_;
};

}  // namespace coin2::exchange::base::feed::replay
